/*************/
/* Variables */
/*************/

extern int st_pos;

extern int **code_area;
extern long **symtab;

extern char **name_area;


/***********/
/* Structs */
/***********/

typedef int object;

struct private_block {
   int task_number;
   struct private_block *next;
   object block[1];
};

/// TODO : Try removing some stuff from this struct.
/// Sync any changes with the backend header files.
typedef struct symtab_entry {
    long obj;
    struct symtab_entry *next;
    char mode;
    char scope;
    unsigned char file_no;
    unsigned char dummy;       /// Try to remove.
    char *name;
    int token;                 /// This could be char, though that might require a little rearranging in fe_shared.h
    int *code;
    int *linetab;              /// Try to remove.
    unsigned firstline;
    struct symtab_entry *temps;
    unsigned num_args;
    int resident_task;
    struct private_block *saved_privates;
    unsigned int stack_space;
} st_entry;

typedef struct IL {
    struct symtab_entry *st;
    struct sline *sl;
    int *misc;
    char *lit;
} il;


/***********/
/* Defines */
/***********/

#define ASSIGN_TEMP_SEGMENT \
be_symtab[i].obj = symtab[i][S_OBJ]; \
if (symtab[i][S_NEXT] == 0) \
    be_symtab[i].next = NULL; \
else \
    be_symtab[i].next = &be_symtab[symtab[i][S_NEXT]]; \
be_symtab[i].mode = symtab[i][S_MODE]; \
be_symtab[i].scope = symtab[i][S_SCOPE]; \
be_symtab[i].file_no = symtab[i][S_FILE_NO];

#define ASSIGN_VAR_SEGMENT \
be_symtab[i].name = malloc(strlen(name_area[symtab[i][S_NAME]]) + 1 * sizeof(char)); \
strcpy(be_symtab[i].name, name_area[symtab[i][S_NAME]]); \
be_symtab[i].token = symtab[i][S_TOKEN];

#define ASSIGN_ROUTINE_SEGMENT \
if (symtab[i][S_CODE] == -1) \
    be_symtab[i].code = NULL; \
else { \
    len = my_int_strlen(code_area[symtab[i][S_CODE]]); \
    be_symtab[i].code = malloc(len * sizeof(int *)); \
    my_int_strncpy(be_symtab[i].code, code_area[symtab[i][S_CODE]], len); \
} \
be_symtab[i].linetab = NULL; \
be_symtab[i].firstline = symtab[i][S_FIRSTLINE]; \
if (symtab[i][S_TEMPS] == 0) \
    be_symtab[i].temps = NULL; \
else \
    be_symtab[i].temps = &be_symtab[symtab[i][S_TEMPS]]; \
be_symtab[i].num_args = symtab[i][S_NUM_ARGS]; \
be_symtab[i].saved_privates = NULL; \
be_symtab[i].resident_task = -1; \
be_symtab[i].stack_space = symtab[i][S_STACK_SPACE];

#define NULL_VAR_SEGMENT \
be_symtab[i].dummy = 0; \
be_symtab[i].name = NULL; \
be_symtab[i].token = 0;

#define NULL_ROUTINE_SEGMENT \
be_symtab[i].code = NULL; \
be_symtab[i].linetab = NULL; \
be_symtab[i].firstline = 0; \
be_symtab[i].temps = NULL; \
be_symtab[i].num_args = 0; \
be_symtab[i].resident_task = -1; \
be_symtab[i].saved_privates = NULL; \
be_symtab[i].stack_space = 0;


/*****************/
/* Special types */
/*****************/

il fe_il;
struct symtab_entry *be_symtab;

extern void my_start_backend(il);
extern void shutdown_gyroe(int);

